package com.lekang.le.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.util.Calendar;
import java.text.SimpleDateFormat;

import com.lekang.common.core.domain.entity.SysUser;
import com.lekang.common.utils.DateUtils;
import com.lekang.common.exception.ServiceException;
import com.lekang.le.domain.ElderlySzh;
import com.lekang.le.domain.NursingItem;
import com.lekang.le.domain.OrderVO;
import com.lekang.le.domain.OrderCreateDTO;
import com.lekang.le.domain.Balance;
import com.lekang.le.mapper.ElderlySzhMapper;
import com.lekang.le.mapper.NursingItemMapper;
import com.lekang.le.mapper.WxUserBindingMapper;
import com.lekang.le.service.IBalanceService;
import com.lekang.le.service.IBillService;
import com.lekang.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.lekang.le.mapper.OrderManagementMapper;
import com.lekang.le.domain.OrderManagement;
import com.lekang.le.service.IOrderManagementService;
import java.math.BigDecimal;

/**
 * 订单管理Service业务层处理
 * 
 * @author yyh
 * @date 2025-10-14
 */
@Service
public class OrderManagementServiceImpl implements IOrderManagementService 
{
    @Autowired
    private OrderManagementMapper orderManagementMapper;
    @Autowired
    private ElderlySzhMapper elderlySzhMapper;
    @Autowired
    private NursingItemMapper nursingItemMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private WxUserBindingMapper wxUserBindingMapper;
    @Autowired
    private IBalanceService balanceService;
    @Autowired
    private IBillService billService;

    /**
     * 查询订单管理
     * 
     * @param id 订单管理主键
     * @return 订单管理
     */
    @Override
    public OrderManagement selectOrderManagementById(Long id)
    {
        return orderManagementMapper.selectOrderManagementById(id);
    }

    /**
     * 查询订单管理列表
     * 
     * @param orderManagement 订单管理
     * @return 订单管理
     */
    @Override
    public List<OrderManagement> selectOrderManagementList(OrderManagement orderManagement)
    {
        List<OrderManagement> orderManagements = orderManagementMapper.selectOrderManagementList(orderManagement);
        for(OrderManagement oo : orderManagements){
           Long elderlyId = oo.getElderlyId();
            ElderlySzh elderlySzh = elderlySzhMapper.selectElderlySzhById(elderlyId);
            oo.setElderly(elderlySzh);
            Long nursingItemId = oo.getNursingItemId();
            NursingItem nursingItem = nursingItemMapper.selectNursingItemById(nursingItemId);
            oo.setNursingItem(nursingItem);
            Long orderUserId = oo.getOrderUserId();
            SysUser sysUser = sysUserMapper.selectUserById(orderUserId);
            oo.setSysUser(sysUser);
        }
        return orderManagements;
    }

    /**
     * 新增订单管理
     * 
     * @param orderManagement 订单管理
     * @return 结果
     */
    @Override
    public int insertOrderManagement(OrderManagement orderManagement)
    {
        orderManagement.setCreateTime(DateUtils.getNowDate());
        return orderManagementMapper.insertOrderManagement(orderManagement);
    }

    /**
     * 修改订单管理
     * 
     * @param orderManagement 订单管理
     * @return 结果
     */
    @Override
    public int updateOrderManagement(OrderManagement orderManagement)
    {
        orderManagement.setUpdateTime(DateUtils.getNowDate());
        return orderManagementMapper.updateOrderManagement(orderManagement);
    }

    /**
     * 批量删除订单管理
     * 
     * @param ids 需要删除的订单管理主键
     * @return 结果
     */
    @Override
    public int deleteOrderManagementByIds(Long[] ids)
    {
        return orderManagementMapper.deleteOrderManagementByIds(ids);
    }

    /**
     * 删除订单管理信息
     * 
     * @param id 订单管理主键
     * @return 结果
     */
    @Override
    public int deleteOrderManagementById(Long id)
    {
        return orderManagementMapper.deleteOrderManagementById(id);
    }

    /**
     * 查询当前用户的订单列表（小程序端使用）
     * 
     * @param userId 用户ID
     * @param orderStatus 订单状态（可选）
     * @return 订单VO列表
     */
    @Override
    public List<OrderVO> selectMyOrders(Long userId, String orderStatus)
    {
        // 查询订单列表
        List<OrderManagement> orderList = orderManagementMapper.selectMyOrders(userId, orderStatus);
        
        // 转换为VO对象
        List<OrderVO> voList = new ArrayList<>();
        for (OrderManagement order : orderList) {
            OrderVO vo = new OrderVO();
            vo.setId(order.getId());
            vo.setOrderNo(order.getOrderNo());
            vo.setServiceName(order.getNursingItemName()); // 护理项目名称
            vo.setElderlyName(order.getElderlyName()); // 老人姓名
            vo.setServiceTime(order.getExpectedServiceTime());
            vo.setPrice(order.getOrderAmount());
            vo.setOrderStatus(order.getOrderStatus());
            vo.setTransactionStatus(order.getTransactionStatus());
            vo.setCreateTime(order.getCreateTime());
            
            // 转换订单状态为文字和样式
            String status = convertOrderStatus(order.getOrderStatus());
            vo.setStatus(status);
            vo.setStatusClass(convertStatusClass(order.getOrderStatus()));
            
            // 设置价格标签
            if ("1".equals(order.getOrderStatus())) {
                vo.setPriceLabel("应付款");
            } else {
                vo.setPriceLabel("实付款");
            }
            
            voList.add(vo);
        }
        
        return voList;
    }
    
    /**
     * 将订单状态数字转换为文字
     * 
     * @param orderStatus 订单状态数字
     * @return 状态文字
     */
    private String convertOrderStatus(String orderStatus) {
        if (orderStatus == null) {
            return "未知";
        }
        switch (orderStatus) {
            case "1":
                return "待支付";
            case "2":
                return "待执行";
            case "3":
                return "已执行";
            case "4":
                return "已完成";
            case "5":
                return "已退款";
            case "6":
                return "已关闭";
            default:
                return "未知";
        }
    }
    
    /**
     * 根据订单状态获取样式类名
     * 
     * @param orderStatus 订单状态
     * @return 样式类名
     */
    private String convertStatusClass(String orderStatus) {
        if (orderStatus == null) {
            return "";
        }
        switch (orderStatus) {
            case "1":
                return "status-dzf";  // 待支付
            case "2":
                return "status-dzx";  // 待执行
            case "3":
                return "status-yxz";  // 已执行
            case "4":
                return "status-ywc";  // 已完成
            case "5":
                return "status-ytk";  // 已退款
            case "6":
                return "status-ygb";  // 已关闭
            default:
                return "";
        }
    }

    /**
     * 取消订单（小程序端使用）
     * 
     * @param orderId 订单ID
     * @param cancelReason 取消原因
     * @return 结果
     */
    @Override
    public int cancelOrder(Long orderId, String cancelReason)
    {
        OrderManagement order = new OrderManagement();
        order.setId(orderId);
        order.setOrderStatus("6"); // 已关闭
        order.setCancelReason(cancelReason);
        order.setUpdateTime(DateUtils.getNowDate());
        return orderManagementMapper.updateOrderManagement(order);
    }

    /**
     * 支付订单（小程序端使用）
     * 支付流程：
     * 1. 查询订单信息
     * 2. 查询老人余额
     * 3. 检查余额是否充足
     * 4. 扣除余额（优先扣预交款，不足再扣押金）
     * 5. 生成账单记录
     * 6. 更新订单状态
     * 
     * @param orderId 订单ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int payOrder(Long orderId)
    {
        // 1. 查询订单信息
        OrderManagement order = orderManagementMapper.selectOrderManagementById(orderId);
        if (order == null) {
            throw new ServiceException("订单不存在");
        }
        
        // 检查订单状态
        if (!"1".equals(order.getOrderStatus())) {
            throw new ServiceException("订单状态异常，无法支付");
        }
        
        // 检查是否已支付
        if ("1".equals(order.getTransactionStatus())) {
            throw new ServiceException("订单已支付，请勿重复支付");
        }
        
        // 获取订单金额和老人ID
        BigDecimal orderAmount = order.getOrderAmount();
        Long elderlyId = order.getElderlyId();
        
        if (orderAmount == null || orderAmount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("订单金额异常");
        }
        
        if (elderlyId == null) {
            throw new ServiceException("老人信息缺失");
        }
        
        // 2. 查询老人的余额记录
        Balance balance = balanceService.selectBalanceByElderlyId(elderlyId);
        if (balance == null) {
            throw new ServiceException("该老人没有余额记录，请联系管理员");
        }
        
        // 获取余额（处理null值）
        BigDecimal prepaymentBalance = balance.getPrepaymentBalance();
        if (prepaymentBalance == null) {
            prepaymentBalance = BigDecimal.ZERO;
        }
        
        BigDecimal depositBalance = balance.getDepositBalance();
        if (depositBalance == null) {
            depositBalance = BigDecimal.ZERO;
        }
        
        // 3. 计算总余额并检查是否充足
        BigDecimal totalBalance = prepaymentBalance.add(depositBalance);
        if (totalBalance.compareTo(orderAmount) < 0) {
            throw new ServiceException("余额不足，当前可用余额：" + totalBalance + "元，需支付：" + orderAmount + "元");
        }
        
        // 4. 计算扣款明细（优先扣预交款）
        BigDecimal prepaymentDeduct; // 从预交款扣除的金额
        BigDecimal depositDeduct;    // 从押金扣除的金额
        
        if (prepaymentBalance.compareTo(orderAmount) >= 0) {
            // 预交款足够，全部从预交款扣除
            prepaymentDeduct = orderAmount;
            depositDeduct = BigDecimal.ZERO;
        } else {
            // 预交款不够，预交款扣完后从押金扣除
            prepaymentDeduct = prepaymentBalance;
            depositDeduct = orderAmount.subtract(prepaymentBalance);
        }
        
        // 5. 扣除余额
        boolean deductSuccess = balanceService.deductBalance(elderlyId, orderAmount);
        if (!deductSuccess) {
            throw new ServiceException("扣除余额失败，支付失败");
        }
        
        // 6. 生成账单记录
        try {
            billService.createOrderBill(order.getOrderNo(), elderlyId, orderAmount, prepaymentDeduct, depositDeduct);
        } catch (Exception e) {
            throw new ServiceException("生成账单失败：" + e.getMessage());
        }
        
        // 7. 更新订单状态
        OrderManagement updateOrder = new OrderManagement();
        updateOrder.setId(orderId);
        updateOrder.setOrderStatus("2"); // 待执行
        updateOrder.setTransactionStatus("1"); // 已支付
        updateOrder.setUpdateTime(DateUtils.getNowDate());
        
        return orderManagementMapper.updateOrderManagement(updateOrder);
    }

    /**
     * 根据订单ID查询订单详情（小程序端使用）
     * 
     * @param orderId 订单ID
     * @return 订单VO
     */
    @Override
    public OrderVO selectOrderDetail(Long orderId)
    {
        OrderManagement order = orderManagementMapper.selectOrderManagementById(orderId);
        if (order == null) {
            return null;
        }

        // 查询关联的老人信息和护理项目信息
        ElderlySzh elderly = null;
        if (order.getElderlyId() != null) {
            elderly = elderlySzhMapper.selectElderlySzhById(order.getElderlyId());
        }

        NursingItem nursingItem = null;
        if (order.getNursingItemId() != null) {
            nursingItem = nursingItemMapper.selectNursingItemById(order.getNursingItemId());
        }

        // 转换为VO
        OrderVO vo = new OrderVO();
        vo.setId(order.getId());
        vo.setOrderNo(order.getOrderNo());
        vo.setServiceName(nursingItem != null ? nursingItem.getName() : "");
        vo.setElderlyName(elderly != null ? elderly.getName() : "");
        vo.setServiceTime(order.getExpectedServiceTime());
        vo.setPrice(order.getOrderAmount());
        vo.setOrderStatus(order.getOrderStatus());
        vo.setTransactionStatus(order.getTransactionStatus());
        vo.setCreateTime(order.getCreateTime());
        vo.setUpdateTime(order.getUpdateTime());
        vo.setRemark(order.getRemark());
        vo.setCancelReason(order.getCancelReason());
        
        // 转换订单状态
        String status = convertOrderStatus(order.getOrderStatus());
        vo.setStatus(status);
        vo.setStatusClass(convertStatusClass(order.getOrderStatus()));
        
        // 设置价格标签
        if ("1".equals(order.getOrderStatus())) {
            vo.setPriceLabel("应付款");
        } else {
            vo.setPriceLabel("实付款");
        }
        
        return vo;
    }

    /**
     * 申请退款（小程序端使用）
     * 
     * @param orderId 订单ID
     * @param refundReason 退款原因
     * @return 结果
     */
    @Override
    public int refundOrder(Long orderId, String refundReason)
    {
        OrderManagement order = new OrderManagement();
        order.setId(orderId);
        order.setOrderStatus("5"); // 已退款
        order.setCancelReason(refundReason); // 使用cancel_reason字段保存退款原因
        order.setUpdateTime(DateUtils.getNowDate());
        return orderManagementMapper.updateOrderManagement(order);
    }

    /**
     * 创建服务订单（小程序端使用）
     * 
     * @param dto 订单创建DTO
     * @return 订单信息（包含订单号、金额等）
     */
    @Override
    public OrderManagement createServiceOrder(OrderCreateDTO dto)
    {
        // 1. 参数校验
        if (dto == null) {
            throw new ServiceException("订单信息不能为空");
        }
        if (dto.getElderlyId() == null) {
            throw new ServiceException("老人ID不能为空");
        }
        if (dto.getNursingItemId() == null) {
            throw new ServiceException("护理项目ID不能为空");
        }
        if (dto.getExpectedServiceTime() == null) {
            throw new ServiceException("期望服务时间不能为空");
        }
        if (dto.getOrderUserId() == null) {
            throw new ServiceException("下单人ID不能为空");
        }

        // 2. 验证期望服务时间必须是明天及以后
        Date now = new Date();
        Calendar tomorrow = Calendar.getInstance();
        tomorrow.setTime(now);
        tomorrow.add(Calendar.DATE, 1);
        tomorrow.set(Calendar.HOUR_OF_DAY, 0);
        tomorrow.set(Calendar.MINUTE, 0);
        tomorrow.set(Calendar.SECOND, 0);
        tomorrow.set(Calendar.MILLISECOND, 0);

        if (dto.getExpectedServiceTime().before(tomorrow.getTime())) {
            throw new ServiceException("期望服务时间必须是明天及以后");
        }

        // 3. 验证护理项目是否存在且启用
        NursingItem nursingItem = nursingItemMapper.selectNursingItemById(dto.getNursingItemId());
        if (nursingItem == null || nursingItem.getIsDeleted() == 1) {
            throw new ServiceException("护理项目不存在或已删除");
        }
        if (nursingItem.getStatus() != 1) {
            throw new ServiceException("护理项目已停用");
        }

        // 4. 验证老人是否存在
        ElderlySzh elderly = elderlySzhMapper.selectElderlySzhById(dto.getElderlyId());
        if (elderly == null || elderly.getIsDeleted() == 1) {
            throw new ServiceException("老人信息不存在或已删除");
        }

        // 5. 验证用户是否存在
        SysUser user = sysUserMapper.selectUserById(dto.getOrderUserId());
        if (user == null || "1".equals(user.getDelFlag())) {
            throw new ServiceException("用户不存在或已删除");
        }

        // 6. 生成订单编号（规则：ORD + yyyyMMddHHmmss + 随机4位）
        String orderNo = generateOrderNo();

        // 7. 创建订单对象
        OrderManagement order = new OrderManagement();
        order.setOrderNo(orderNo);
        order.setElderlyId(dto.getElderlyId());
        order.setNursingItemId(dto.getNursingItemId());
        order.setOrderAmount(nursingItem.getPrice()); // 从护理项目获取价格
        order.setExpectedServiceTime(dto.getExpectedServiceTime());
        order.setOrderUserId(dto.getOrderUserId());
        order.setOrderStatus("1"); // 1=待支付
        order.setTransactionStatus("0"); // 交易状态：0=待支付（数字格式）
        order.setRemark(dto.getRemark());
        order.setCreateTime(DateUtils.getNowDate());
        order.setUpdateTime(DateUtils.getNowDate());
        order.setIsDeleted(0L);

        // 8. 插入订单
        int result = orderManagementMapper.insertOrderManagement(order);
        if (result <= 0) {
            throw new ServiceException("创建订单失败");
        }

        // 9. 返回订单信息
        return order;
    }

    /**
     * 生成订单编号
     * 规则：ORD + yyyyMMddHHmmss + 随机4位数字
     * 
     * @return 订单编号
     */
    private String generateOrderNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String datePart = sdf.format(new Date());
        
        // 生成4位随机数字
        int random = (int) ((Math.random() * 9000) + 1000);
        
        return "ORD" + datePart + random;
    }

    /**
     * 关闭超时未支付的订单（定时任务使用）
     * 查询所有状态为"待支付"且超过10分钟的订单，自动关闭
     * 
     * @return 关闭的订单数量
     */
    @Override
    public int closeTimeoutOrders()
    {
        // 计算10分钟前的时间点
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -10);
        Date timeoutThreshold = calendar.getTime();
        
        // 查询所有待支付的订单
        OrderManagement queryOrder = new OrderManagement();
        queryOrder.setOrderStatus("1"); // 待支付
        List<OrderManagement> orders = orderManagementMapper.selectOrderManagementList(queryOrder);
        
        int closedCount = 0;
        
        // 遍历订单，检查是否超时
        for (OrderManagement order : orders) {
            if (order.getCreateTime() != null && order.getCreateTime().before(timeoutThreshold)) {
                // 订单超过10分钟未支付，关闭订单
                OrderManagement updateOrder = new OrderManagement();
                updateOrder.setId(order.getId());
                updateOrder.setOrderStatus("6"); // 已关闭（订单表使用数字）
                updateOrder.setCancelReason("支付超时自动关闭");
                updateOrder.setUpdateTime(DateUtils.getNowDate());
                
                int result = orderManagementMapper.updateOrderManagement(updateOrder);
                if (result > 0) {
                    closedCount++;
                }
            }
        }
        
        return closedCount;
    }
}
